package com.story.web.controllers;

import java.util.Date;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.LockedAccountException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

import com.story.domain.Admin;
import com.story.domain.LoginInfo;
import com.story.domain.Page;
import com.story.domain.User;
import com.story.model.emums.LoginType;
import com.story.service.IAdminService;
import com.story.service.ILoginInfoService;
import com.story.service.IUserService;
import com.story.web.shiro.token.StoryLoginToken;
import com.story.web.utils.DateUtils;
import com.story.web.utils.WebUtils;

@Controller
@RequestMapping("/manager")
public class ManagerController extends BaseController {

	private static final String ADMIN_LOGIN_TYPE = LoginType.ADMIN.toString();

	@Autowired
	private ILoginInfoService loginInfoService;

	@Autowired
	private IAdminService adminService;

	@RequestMapping("/index")
	public String showIndex(Model model) {
		Subject subject = SecurityUtils.getSubject();
		Session session = WebUtils.getSession(subject);
		String sessionid = session.getId().toString();
		Map<String, Object> loginInfoMap = (Map<String, Object>) session
				.getAttribute(sessionid);
		model.addAttribute("loginInfoMap", loginInfoMap);
		return "manager/index";
	}

	@RequestMapping(value = "/registe/do", method = RequestMethod.POST)
	public String doRegiste(@Validated Admin admin, BindingResult result,
			RedirectAttributes redirect, HttpServletRequest request) {
		String msg = "";
		Map<String, String> map = new HashMap<String, String>();
		if (result.hasFieldErrors()) {
			List<FieldError> errors = result.getFieldErrors();
			for (int i = 0; i < errors.size(); i++) {
				map.put(errors.get(i).getField(), errors.get(i)
						.getDefaultMessage());
			}
			redirect.addFlashAttribute("errors", map);
			return "redirect:/manager/registe";
		}
		if (adminService.checkUsernameExisted(admin.getUsername())) {
			redirect.addFlashAttribute("error", "用户已存在！");
			return "redirect:/manager/registe";
		}
		Admin initAdmin = WebUtils.init(request, admin);
		adminService.addAdmin(initAdmin);
		msg = "注册成功!";
		redirect.addFlashAttribute("success", msg);
		return "redirect:/manager/login";
	}

	@RequestMapping(value = "/login/do", method = RequestMethod.POST)
	@ResponseBody
	public Map<String, Object> doLogin(String username, String password,
			String verifyNumber, HttpServletRequest request,
			HttpServletResponse response) {
		Map<String, Object> map = new HashMap<String, Object>();
		String verifyError = (String) request.getAttribute("shiroLoginFailure");
		if (verifyError != null && verifyError.equals("jCaptcha.error")) {
			map.put("status", "1");
			map.put("msg", "验证码错误!");
			return map;
		}
		Subject subject = SecurityUtils.getSubject();
		if (!subject.isAuthenticated()) {
			StoryLoginToken token = new StoryLoginToken(username, password,
					ADMIN_LOGIN_TYPE);
			try {
				subject.login(token);
				Session session = WebUtils.getSession(subject);
				String sessionId = session.getId().toString();
				Date lastLoginTime = WebUtils
						.getLastLoginTimeFromCookie(request);
				if (lastLoginTime == null) {
					WebUtils.writeLoginTimeToCookie(response);
					lastLoginTime = WebUtils
							.getLastLoginTimeFromCookie(request);
				} else {
					Map<String, Object> loginInfoMap = new LinkedHashMap<String, Object>();
					loginInfoMap.put("loginName", username);
					loginInfoMap.put("lastLoginTime", DateUtils
							.formatDateToString(lastLoginTime,
									"yyyy年M月d日 hh:mm:ss"));
					loginInfoMap.put("loginIp",
							WebUtils.getCustomerRealIp(request));
					session.setAttribute(sessionId, loginInfoMap);
					WebUtils.writeLoginTimeToCookie(response);
				}
				LoginInfo loginInfo = new LoginInfo();
				loginInfo.setLoginName(username);
				loginInfo.setLoginType(ADMIN_LOGIN_TYPE);
				loginInfo.setLoginIp(WebUtils.getCustomerRealIp(request));
				loginInfo.setLoginTime(new Date(System.currentTimeMillis()));

				loginInfoService.recordLoginInfo(loginInfo);
				map.put("status", 0);
				map.put("msg", "登陆成功，正在跳转中...");
			} catch (UnknownAccountException ue) {
				map.put("status", 1);
				map.put("msg", "未找到此用户！");
			} catch (IncorrectCredentialsException ice) {
				map.put("status", 1);
				map.put("msg", "用户名或密码错误!");
			} catch (LockedAccountException lae) {
				map.put("status", 1);
				map.put("msg", "账号已冻结，请联系管理员!");
			} catch (Exception e) {
				map.put("status", 1);
				map.put("msg", "登陆出现错误...");
				e.printStackTrace();
			}
		}
		return map;
	}

	@RequestMapping("/logout")
	public String doLogout() {
		Subject subject = SecurityUtils.getSubject();
		if (subject.isAuthenticated()) {
			subject.logout();
		}
		return "redirect:login";
	}

}
